package com.ta.httplib;

import android.text.TextUtils;

import java.io.File;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import com.ta.httplib.utils.CommonUtils;
import com.ta.httplib.callback.DownloadCallback;
import com.ta.httplib.core.DownloadCore;
import com.ta.httplib.callback.DownloadListener;
import com.ta.httplib.interceptor.HttpLogInterceptor;
import com.ta.httplib.utils.FileUtils;
import com.ta.httplib.utils.LogUtils;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * 网络请求单例
 */
public abstract class HttpCore {

    public abstract String getBaseUrl();

    public abstract Map<String, String> getHeaders();

    private static final Charset UTF8 = Charset.forName("UTF-8");

    public Interceptor getInterceptor() {
        return new HttpLogInterceptor() {
            @Override
            public Map<String, String> getHeaders() {
                return HttpCore.this.getHeaders();
            }
        };
    }

    /**
     * 初始化okHttpClient
     */
    private OkHttpClient initOkHttp() {
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        if (BuildConfig.IS_DEBUG) {
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        } else {
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
        }

        return new OkHttpClient.Builder().addInterceptor(getInterceptor()).connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .addInterceptor(loggingInterceptor)
                .build();
    }

    /**
     * 创建retrofit对象
     */
    public <T> T createRetrofitForJson(Class<T> clazz) {
        Retrofit retrofit = new Retrofit.Builder().client(initOkHttp()).baseUrl(getBaseUrl())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create()).build();
        return retrofit.create(clazz);
    }

    public <T> T createRetrofitForStr(Class<T> clazz) {
        Retrofit retrofit = new Retrofit.Builder().client(initOkHttp()).baseUrl(getBaseUrl())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(ScalarsConverterFactory.create()).build();
        return retrofit.create(clazz);
    }

    /**
     * 下载
     *
     * @param url      下载文件url
     * @param filePath 保存的位置
     * @param callback 进度回调
     */
    public static void download(final String url, final String filePath, final DownloadCallback callback) {
        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(filePath)) {
            if (null != callback) {
                callback.onError("url or path empty");
            }
            return;
        }
        File oldFile = new File(filePath);
        if (oldFile.exists()) {
            if (null != callback) {
                callback.onFinish(oldFile);
            }
            return;
        }

        DownloadListener listener = new DownloadListener() {
            @Override
            public void onStart(ResponseBody responseBody) {
                FileUtils.saveFile(responseBody, url, filePath, callback);
            }
        };

        DownloadCore.downloadFile(url, CommonUtils.getTempFile(url, filePath).length(), listener, new Observer<ResponseBody>() {
            @Override
            public void onSubscribe(Disposable d) {
                if (null != callback) {
                    callback.onStart(d);
                }
            }

            @Override
            public void onNext(final ResponseBody responseBody) {

            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                LogUtils.logE("onError " + e.getMessage());
                if (null != callback) {
                    callback.onError(e.getMessage());
                }
            }

            @Override
            public void onComplete() {
                LogUtils.logE("download onComplete ");
            }
        });
    }
}